iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
AI Engineering

從對話到照護:30 天打造高齡智慧健康 AI Companion系列 第 2

Day 02|先讓 AI 聽懂你:從 Speech-to-Text 開始

  • 分享至 

  • xImage
  •  

昨天先整理了這次 AI Companion 想完成的整體方向。

如果希望 AI 不只是一個文字聊天機器人,而是真的能成為日常生活中的陪伴角色,那麼第一個要解決的問題其實很直接:

AI 要怎麼聽懂使用者說了什麼?

尤其這次的應用情境是高齡智慧健康照護,相較於打字,我希望主要的互動方式可以以「語音」為主。

例如使用者可以直接說:

昨天晚上沒有睡好。
今天膝蓋有點不舒服。
晚餐吃得比較少。

這些原本只是日常對話中的內容,未來都有可能成為 Health Memory 或健康狀態分析的資料來源。

不過在做到這些功能以前,今天先專心解決一件事情:

讓 AI 穩定、快速地把語音轉換成文字。


Speech-to-Text 是什麼?

Speech-to-Text,簡稱 STT,就是將人說話的聲音轉換成文字。

整個 AI Companion 的語音流程,可以先簡化成:

使用者說話
↓
Speech-to-Text
↓
文字
↓
LLM
↓
回覆

STT 可以說是整個語音系統最前面的入口。

如果辨識結果錯誤,後面的 LLM、Memory 或 RAG 即使做得再完整,也可能因為輸入錯誤而產生不正確的結果。

例如使用者說:

我今天有點頭痛

如果 STT 辨識錯誤,後續對話甚至健康資訊擷取都可能受到影響。

所以第一步,就是先把語音辨識做好。


為什麼選 Whisper?

這次我先使用 Whisper 作為 Speech-to-Text 模型,並選擇:

Whisper Large V3 Turbo

Whisper 支援多語言語音辨識,中文的辨識效果也不錯。

相比完整的 Large V3,Turbo 版本在辨識速度與效果之間取得不錯的平衡,對即時語音應用來說比較適合。

另外,目前主要是在 Apple Silicon 的 Mac 上進行開發,因此我使用 MLX 版本來執行模型。

MLX 是針對 Apple Silicon 設計的機器學習框架,可以利用 Mac 的統一記憶體與 GPU 進行推論。

所以第一版流程很單純:

Microphone
↓
Audio
↓
MLX Whisper
↓
Text

先確認從麥克風輸入語音,到最後輸出文字這條流程可以正常運作。


第一版:錄完再辨識

最簡單的 STT 做法就是:

開始錄音
↓
使用者說話
↓
停止錄音
↓
Whisper 辨識
↓
輸出文字

這種方法實作很簡單,而且辨識效果通常也不錯。

但很快就會遇到一個問題:

使用者說話的時候,系統幾乎沒有任何反應。

假設使用者說了 10 秒,就必須先把整段話說完,再等待 Whisper 完成辨識。

對一般錄音轉文字來說可能沒什麼問題,但如果要做的是 AI Companion,互動感就會比較差。

所以接下來我加入了 Rolling Transcription。


Rolling Transcription:邊講邊辨識

Rolling Transcription 的想法是:

不要等整段語音全部說完,而是每隔一段時間,就拿目前收到的音訊進行一次辨識。

例如:

0~2 秒 → 辨識
1~3 秒 → 再辨識
2~4 秒 → 再辨識

這樣使用者在講話的過程中,就可以持續看到文字更新。

例如一開始可能是:

我今天

接著變成:

我今天早上

最後變成:

我今天早上沒有吃早餐

相較於講完整句才看到結果,這樣的互動體驗會自然很多。

目前我的 Rolling Window 大約使用 2 秒左右的音訊來進行辨識更新。


Rolling Transcription 不等於 Streaming ASR

做到這裡時,其實很容易覺得:

文字已經可以即時更新,那這不就是 Streaming ASR 嗎?

但其實兩者不完全一樣。

Rolling Transcription 本質上還是:

取得一段音訊
↓
送進 Whisper
↓
重新推論
↓
更新文字

只是這個流程持續重複,所以看起來像即時辨識。

真正的 Streaming ASR 通常會持續接收音訊,並保留前面語音的狀態,不需要每次重新處理一整段音訊。

因此目前這個版本比較像是:

利用 Rolling Window 做出接近即時辨識的效果。

真正的 Streaming ASR,之後會再另外實作並進行比較。


加入 VAD:AI 怎麼知道我講完了?

做到 Rolling STT 之後,下一個問題是:

系統怎麼知道使用者什麼時候開始說話,又什麼時候講完?

如果沒有判斷機制,就只能讓使用者自己按下開始錄音和停止錄音。

所以我加入了 VAD(Voice Activity Detection)。

VAD 的功能很簡單,就是判斷目前的音訊中:

有沒有人正在說話?

加入 VAD 之後,流程就變成:

Microphone
↓
VAD
↓
Speech Start
↓
開始收集語音
↓
Rolling STT
↓
偵測到一段時間沒有說話
↓
Speech End

這樣就可以讓系統自動判斷一句話是否已經結束。

而 Speech Start / Speech End 之後也會繼續用在 Barge-in 與完整 Streaming Voice Pipeline 中。


為什麼還需要 Final STT?

Rolling Transcription 雖然可以快速顯示文字,但結果不一定穩定。

例如一開始可能辨識成:

我今天晚上

過一下又修正成:

我今天晚餐

最後才變成:

我今天晚餐吃得比較少

這是因為模型在拿到更多上下文後,可能會修正前面的結果。

所以我的設計是:

Rolling STT
→ 負責即時顯示

Speech End
↓
Final STT
→ 使用完整音訊重新辨識

也就是把「即時性」和「最終結果」分開處理。

Rolling STT 讓使用者可以快速看到文字,而 Final STT 則負責產生最後真正送給後續 LLM 的內容。


目前的 STT Pipeline

目前第一版的語音辨識流程變成:

使用者說話
↓
Microphone
↓
VAD
↓
Rolling STT / Partial Result
↓
Speech End
↓
Final STT
↓
完整文字

其中:

Rolling STT → 提供即時回饋
Final STT   → 提供較穩定的最終結果

這也會成為後續語音系統的基礎。


實際速度測試

目前在 Mac 上使用 MLX Whisper Large V3 Turbo 進行測試。

其中一次測試結果:

音訊長度:4.5 秒
辨識時間:約 1.31 秒
RTF:約 0.29

RTF(Real-Time Factor)的計算方式是:

RTF = 處理時間 / 音訊長度

因此:

1.31 / 4.5 ≈ 0.29

RTF 小於 1,代表模型處理速度比音訊本身的播放速度快。

以目前第一版 Prototype 來說,這個速度已經可以作為後續即時語音互動的基礎。


今天遇到的問題

今天主要遇到的問題是:

即時性和辨識準確度要怎麼平衡?

Rolling Window 太短,模型拿到的上下文比較少,辨識結果可能不穩定;Window 太長,則會增加等待時間。

另外還需要持續調整:

Rolling Window 長度
更新頻率
VAD 的 Speech End 判斷
Final STT 的修正方式

這些參數都會影響之後的 Streaming Voice Pipeline。


Day 02 完成

今天完成了第一版語音辨識流程:

Microphone
↓
VAD
↓
Rolling Transcription
↓
Speech End
↓
Final STT
↓
Text

未來使用者在日常對話中提到的睡眠、飲食或身體狀況,也會先透過這條 STT Pipeline 轉成文字,再交給後續的 Health Memory 處理。

今天先完成 AI Companion 的第一個能力:

讓 AI 聽懂使用者說了什麼。

下一篇 Day 03,就要讓 AI 開始真正「開口說話」。

Day 03|讓 AI 開始說話:從 Text-to-Speech 到自然語音。


上一篇
Day 01|從聊天到照護:我想做一個怎樣的 AI Companion?
下一篇
Day 03|讓 AI 開口說話:從 Text-to-Speech 開始
系列文
從對話到照護:30 天打造高齡智慧健康 AI Companion6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言